// -*- Java -*-
/*
 * <copyright>
 * 
 *  Copyright (c) 2002
 *  Institute for Information Processing and Computer Supported New Media (IICM),
 *  Graz University of Technology, Austria.
 * 
 * </copyright>
 * 
 * <file>
 * 
 *  Name:    Input.java
 * 
 *  Purpose: Input reads and parses the KWIC input file
 * 
 *  Created: 05 Nov 2002 
 * 
 *  $Id$
 * 
 *  Description:
 *    Input reads and parses the KWIC input file
 * </file>
 */

package kwic.es;

/*
 * $Log$
 */

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import java.util.ArrayList;

/**
 * An object of the Input class is responsible for reading and parsing the
 * content of a KWIC input file. The format of the KWIC input file is as
 * follows:
 * <ul>
 * <li>Lines are separated by the line separator character(s) (on Unix '\n', on
 * Windows '\r\n')
 * <li>Each line consists of a number of words. Words are delimited by any
 * number and combination of the space chracter (' ') and the horizontal
 * tabulation chracter ('\t').
 * </ul>
 * The entered data is parsed and stored in memory as an instance of the
 * LineStorageWrapper class. The data is parsed in the following way:
 * <ul>
 * <li>All line separators are removed from the data; for each new line in the
 * file a new line is added to the LineStorageWrapper instance
 * <li>All horizontal tabulation word delimiters are removed
 * <li>All space character word delimiters are removed
 * <li>From characters between any two word delimiters a new string is created;
 * the new string is added to the LineStorageWrapper instance.
 * </ul>
 * 
 * @author dhelic
 * @version $Id$
 */

public class Input {

	// ----------------------------------------------------------------------
	/**
	 * Fields
	 * 
	 */
	// ----------------------------------------------------------------------

	// ----------------------------------------------------------------------
	/**
	 * Constructors
	 * 
	 */
	// ----------------------------------------------------------------------

	// ----------------------------------------------------------------------
	/**
	 * Methods
	 * 
	 */
	// ----------------------------------------------------------------------

	// ----------------------------------------------------------------------
	/**
	 * This method reads and parses a KWIC input file. If an I/O exception
	 * occurs during the execution of this method, an error message is shown and
	 * program exits.
	 * 
	 * @param file
	 *            name of KWIC input file
	 * @param line_storage
	 *            holds the parsed data
	 */

	public void parse(String file, LineStorageWrapper line_storage) {
		try {
			BufferedReader reader = new BufferedReader(new FileReader(file));

			String line = reader.readLine();
			while (line != null) {
				StringTokenizer tokenizer = new StringTokenizer(line); // whitespaces
																		// are
																		// default
																		// delimiters
				if (tokenizer.countTokens() > 0) {
					ArrayList<String> words = new ArrayList<String>();
					while (tokenizer.hasMoreTokens())
						words.add(tokenizer.nextToken());

					String[] line_rep = new String[words.size()];
					for (int i = 0; i < line_rep.length; i++)
						line_rep[i] = (String) words.get(i);

					line_storage.addLine(line_rep);
				}

				line = reader.readLine();
			}

		} catch (FileNotFoundException exc) {
			exc.printStackTrace();
			System.err.println("KWIC Error: Could not open " + file + "file.");
			System.exit(1);
		} catch (IOException exc) {
			exc.printStackTrace();
			System.err.println("KWIC Error: Could not read " + file + "file.");
			System.exit(1);
		}
	}

	// ----------------------------------------------------------------------

	/**
	 * This method reads and parses by Man Input.
	 * 
	 * @param line_storage
	 *            holds the parsed data
	 * @return true Print Result
	 * 
	 */
	public boolean parse(LineStorageWrapper line_storage) {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		final String MENU = "Add, Delete, Print, Index, Quit:";
		try {
			System.out.print(MENU);
			String line = in.readLine();
			while (line != null) {
				char ch = line.charAt(0);
				switch (ch) {
				case 'a':
					line = in.readLine();
					parseAdd(line_storage, line);
					break;
				case 'd':
					line = in.readLine();
					parseDel(line_storage, line);
					break;
				case 'p':
					return true;
				case 'i':
					Index.count(line_storage);
				case 'q':
				default:
					parseQuit();
					break;
				}
				System.out.print(MENU);
				line = in.readLine();
			}
		} catch (Exception e) {
			// e.printStackTrace();
			System.err.println("KWIC Error: Error Input or No Input");
			System.exit(1);
		}

		return false;

	}

	/**
	 * This is a private method to add lines
	 * 
	 * @param line_storage
	 *            holds the parsed data
	 * @param line
	 *            Input String
	 */
	private void parseAdd(LineStorageWrapper line_storage, String line) {
		try {
			StringTokenizer tokenizer = new StringTokenizer(line);
			if (tokenizer.countTokens() > 0) {
				ArrayList<String> words = new ArrayList<String>();
				while (tokenizer.hasMoreTokens())
					words.add(tokenizer.nextToken());

				String[] line_rep = new String[words.size()];
				for (int i = 0; i < line_rep.length; i++)
					line_rep[i] = (String) words.get(i);
				line_storage.addLine(line_rep);
			}
		} catch (Exception exc) {
			exc.printStackTrace();
			System.err.println("KWIC Error: Could not get user inputs.");
			System.exit(1);
		}
	}

	/**
	 * This is a private method to del lines
	 * 
	 * @param line_storage
	 *            holds the parsed data
	 * @param line
	 *            Input String to del
	 */
	private void parseDel(LineStorageWrapper line_storage, String line) {
		int num = line_storage.getLineCount();
		boolean delSuccess = false;

		for (int i = 0; i < num; i++) {
			if (line.equals(line_storage.getLineAsString(i))) {
				line_storage.deleteLine(i);
				delSuccess = true;
				break;
			}
		}
		if (!delSuccess)
			System.out.println("Delete Line Failure!");
	}

	/**
	 * This is a private method to quit
	 * 
	 */
	private void parseQuit() {
		System.exit(0);
	}

	// ----------------------------------------------------------------------
	/**
	 * Inner classes
	 * 
	 */
	// ----------------------------------------------------------------------

}
